<--- %%NOBANNER%% --> dir.sas
 BackForward

/*-------------------<-- Start of Description -->--------------------\
| List the contents of a directory into a dataset.                   |
|---------------------<--End of Description -->----------------------|
|--------------------------------------------------------------------|
|-----------<-- Start of Files or Arguements Needed-->---------------|
| Arguments:                                                         |
|    path - the directory you want to list;                          |
|    outdata - the output data set to save the contents of the       |
|              directory.                                            |
|------------<-- End of Files or Arguements Needed-->----------------|
|--------------------------------------------------------------------|
|------------------<-- Start of Files Created-->---------------------|
| Example: %dir(directory=d:\web\sasmacros\,outdata=dirdata);        |
| Usage: %dir(directory=, outdata=);                                 |
\------------------<-- Start of Files Created-->--------------------*/
%macro dir/parmbuff;
/*--------------------------------------------\
| Author:  Duo Zhou;                          |
| Created: 10-30-2001 8:39pm;                 |
| Purpose: List the contents of a directory;  |
\--------------------------------------------*/
options noxwait noxsync;
x 'Exit';
%local dirbuff outbuff _tmplast_;
%let _tmplast_=&syslast;
%let dirbuff=%sysfunc(dequote(%qscan(&syspbuff,1,%str((),))));
%let outbuff=%sysfunc(dequote(%qscan(&syspbuff,2,%str((),))));
%let linesize = %SYSFUNC(GETOPTION(linesize));
%if (%index(%quote(&syspbuff),%quote(=))) %then %do;
   %if (%index(%quote(&dirbuff),%quote(=))) %then %do;
      %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dirbuff))))),%quote(DIR=)))
          or (%index(%quote(%upcase(%sysfunc(compress(%quote(&dirbuff))))),%quote(PATH=)))
          or (%index(%quote(%upcase(%sysfunc(compress(%quote(&dirbuff))))),%quote(DIRECTORY=))) %then %do;
         %let directory=%qscan(&dirbuff,2,%str(=));
         %if (%index(%quote(&outbuff),%quote(=))) %then %do;
            %if (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DATA=))) %then 
               %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
            %else %let outdata=%qscan(&outbuff,2,%str(=));
         %end;
         %else %let outdata=&outbuff;
      %end;
      %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dirbuff))))),%quote(DATA=))) %then %do;
         %let outdata=%qscan(&dirbuff,2,%str(=));
         %if (%index(%quote(&outbuff),%quote(=))) %then %do;
            %if (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DIR=)))
                and (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(PATH=)))
                and (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DIRECTORY=)))
                %then %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
            %else %let directory=%qscan(&outbuff,2,%str(=));
         %end;
         %else %let directory=&outbuff;
      %end;
      %else %put ==> Alert! Keyword parameter "%qscan(&dirbuff,1,%str(=))" is not defined!;
   %end;
   %else %if (%index(%quote(&outbuff),%quote(=))) %then %do;
      %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DIR=)))
          or (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(PATH=)))
          or (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DIRECTORY=))) %then %do;
         %let directory=%qscan(&outbuff,2,%str(=));
         %let outdata=&dirbuff;
      %end;
      %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(DATA=))) %then %do;
         %let directory=&dirbuff;
         %let outdata=%qscan(&outbuff,2,%str(=));
      %end;
      %else %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
   %end;
%end;
%else %do;
   %let directory=&dirbuff;
   %let outdata=&outbuff;
%end;
%if (%quote(&directory) ne) %then %let directory=%sysfunc(dequote(&directory));
%let olddir=&directory;
%if (%length(%trim(%left(&directory))) >1) %then %do;
   %if (%quote(%substr(&directory, %length(&directory), 1)) ne %quote(\)) %then 
      %let directory=&directory.\;
   %let ddir=%substr(&directory, 1, %eval(%length(&directory)-1));
%end;
%else %let ddir=;
%let dirrc=%sysfunc(filename(dirrf,&directory));
%let psid=%sysfunc(DOPEN(&dirrf));
%if &psid %then %do;
   %let today=%sysfunc(date(),mmddyy6.);
   %let workdir=%sysfunc(pathname(work));
   /** Create Temporary Directory List Output in the Working Directory **/
   %sysexec dir "&directory" > "&workdir.\_temp.&today."; x 'Exit';
   /** Read in Directory List Output **/
   %if (%quote(%upcase(&SYSSCPL)) eq WIN_NT) %then %do;
      DATA _tmp1;
         infile "&workdir\_temp.&today." length=linelen;
         length line $ 2000  memname $ 100;
         format fdatime datetime18. fsize comma13.;
         input @1 line $ varying2000. linelen;
         if verify(substr(line, 1, 8), '0123456789/')=0;
         if upcase(substr(line, 16,1))='A' then
            fdatime=dhms(input(substr(line,1,8), mmddyy10.), input(substr(line,11,2),2.), input(substr(line,14,2),2.), 0);
         else if upcase(substr(line, 16,1))='P' then
            fdatime=dhms(input(substr(line,1,8), mmddyy10.), (input(substr(line,11,2),2.)+12), input(substr(line,14,2),2.), 0);
         if index(upcase(substr(line, 25, 15)), 'DIR') then do;
            fsize=.;
            memname =trim(left('<'||substr(line, 40, (length(line)-39))))||'>';
         end;
         else do;
            fsize=input(substr(line, 25, 15), comma14.);
            memname =trim(left(substr(line, 40, (length(line)-39))));
         end;
         keep memname fsize fdatime;
         label memname = "Member Name" fsize="File Size" fdatime="Last Modified Time";
      run;
   %end;
   %else %if (%quote(%upcase(&SYSSCPL)) eq WIN_PRO) %then %do;
      DATA _tmp1;
         infile "&workdir\_temp.&today." length=linelen;
         length line $ 2000  memname $ 100;
         format fdatime datetime18. fsize comma13.;
         input @1 line $ varying2000. linelen;
         if verify(substr(line, 1, 8), '0123456789/')=0;
         if upcase(substr(line, 18,1))='A' then
            fdatime=dhms(input(substr(line,1,10), mmddyy10.), input(substr(line,13,2),2.), input(substr(line,16,2),2.), 0);
         else if upcase(substr(line, 18,1))='P' then
            fdatime=dhms(input(substr(line,1,10), mmddyy10.), (input(substr(line,13,2),2.)+12), input(substr(line,16,2),2.), 0);
         if index(upcase(substr(line, 25, 15)), 'DIR') then do;
            fsize=.;
            memname =trim(left('<'||substr(line, 40, (length(line)-39))))||'>';
         end;
         else do;
            fsize=input(substr(line, 25, 15), comma14.);
            memname =trim(left(substr(line, 40, (length(line)-39))));
         end;
         keep memname fsize fdatime;
         label memname = "Member Name" fsize="File Size" fdatime="Last Modified Time";
      run;
   %end;
   %else %if (%quote(%upcase(&SYSSCPL)) eq WIN_98) or (%quote(%upcase(&SYSSCPL)) eq WIN_95) %then %do;
      DATA _tmp1;
         infile "&workdir\_temp.&today." length=linelen;
         length line $ 2000  memname $ 100;
         format fdatime datetime18. fsize comma13.;
         input @1 line $ varying2000. linelen;
         if verify(substr(line, 29, 8), '0123456789-')=0;
         if upcase(substr(line, 43,1))='A' then
            fdatime=dhms(input(substr(line,29,8), mmddyy10.), input(substr(line,38,2),2.), input(substr(line,41,2),2.), 0);
         else if upcase(substr(line, 43,1))='P' then
            fdatime=dhms(input(substr(line,29,8), mmddyy10.), (input(substr(line,38,2),2.)+12), input(substr(line,41,2),2.), 0);
         if index(upcase(substr(line, 16, 5)), 'DIR') then do;
            fsize=.;
            memname =trim(left('<'||substr(line, 45, (length(line)-44))))||'>';
         end;
         else do;
            fsize=input(substr(line, 21, 7), comma14.);
            memname =trim(left(substr(line, 45, (length(line)-44))));
         end;
         keep memname fsize fdatime;
         label memname = "Member Name" fsize="File Size" fdatime="Last Modified Time";
      run;
   %end;
   /* Delete Temporary Directory List Output */
   %sysexec del "&workdir\_temp.&today."; x 'Exit';
   /** Get some information available only to sas system **/
   data _tmp2;
      length foption $ 200 charval $ 400;
      keep memname foption charval;
      rc=filename("mydir","&directory");
      did=dopen("mydir");
      memcount=dnum(did);
      do _i_=1 to memcount;
         memname=dread(did,_i_);
         rc=FILENAME("myfile", "&directory"||trimn(left(memname)));
         fid = FOPEN("myfile");                 /* open file       */
         foption=" ";
         charval=" ";
         if fid>0 then do;
            numopts=FOPTNUM(fid);  /* get number of information items */
            do _k_=1 to numopts;
               option = FOPTNAME(fid,_k_);
               if trim(left(foption)) ne " " then do;
                  foption = trimn(left(foption))||", "||option;
                  if not index(upcase(FINFO(fid,upcase(option))), upcase("&ddir")) then do;
                     if trim(left(charval)) ne " " then
                        charval  = trimn(left(charval))||", "||FINFO(fid,upcase(option));
                     else charval  = FINFO(fid,upcase(option));
                  end;
               end;
               else do;
                  foption = option;
                  if not index(upcase(FINFO(fid,upcase(option))), upcase("&ddir")) then
                     charval  = FINFO(fid,upcase(option));
               end;
            end;
         end;
         else do;
            numopts=doptnum(did);
            if not missing(numopts) then do;
               do _k_=1 to numopts;
                  option=doptname(did,_k_);
                  if trim(left(foption)) ne " " then do;
                     foption = trimn(left(foption))||", "||option;
                     if not index(upcase(dinfo(did,upcase(option))), upcase("&ddir")) then do;
                        if trim(left(charval)) ne " " then
                           charval=trimn(left(charval))||", "||dinfo(did,upcase(option));
                        else charval  = FINFO(fid,upcase(option));
                     end;
                  end;
                  else do;
                     foption = option;
                     if not index(upcase(dinfo(did,upcase(option))), upcase("&ddir")) then
                        charval  = dINFO(did,upcase(option));
                  end;
               end;
            end;
         end;
         rc = FCLOSE(fid);                      /* close file      */
         rc = FILENAME("myfile");
         if indexw(upcase(foption), 'DIRECTORY') then memname=trimn(left("<"||memname))||">";
         output;
      end;
      label memname="Member Name" foption="Member Type" charval="Member Info";
   run;
   proc sort data=_tmp2; by memname; run; proc sort data=_tmp1; by memname; run;
   data _diropts;
      merge _tmp2(in=in2 keep=memname foption charval) _tmp1(keep=memname fsize fdatime);
      by memname;
      if in2;
   run;
   proc print data=_diropts label;
   title "Contents of Directory &directory:";
   run;
   %if &outdata ne %then %do; data &outdata; set _diropts; run; %end;
   %else %let syslast=&_tmplast_;
   proc datasets library=work nolist; delete _tmp1 _tmp2 _diropts; run;quit;
%end;
%else %put ==> Alert! The directory "&olddir" does%str(%')t exist.;
%mend dir;